;  Base file for project 4
;  ECE 2504 fall 2007
;  Kevin Green

	list P=16F84
	include	P16F84.INC
; turn off the watchdog timer to fix odd behavior on long runs.
 	__CONFIG _HS_OSC&_WDT_OFF&_PWRTE_ON&_CP_OFF 

; Define the direction bit types
f	equ	1
w	equ	0



; Define the data storage locations
; These definitions at 0x20-0x29 are supplied to the user and must not be modified
; The TAs will use the locations for the variables (avg through n0) as part
; of the validation, so they must be located in locations 0x20 through 0x29.
			org	0x20
avg			res	1	;the average of the last 4 sensor readings

asciiavg		res 	3	;the decimal equivalent of the average, in ASCII
							;one byte for the ASCII character for each decimal digit.


inval			res 	1	;the last 4-bit sensor value read, its upper 4 bits are 0
					;after the interrupt returns. 

semaphore		res	1	;an indicator that a new sensor value has been loaded into inval

;  The four 8-bit values used to compute the average, with n3 being the most recent and n0 being
;  the least recent.
n3			res 1
n2			res	1
n1			res	1
n0			res	1

v3	equ	0x33	;monitor n values
v2	equ 0x32
v1	equ 0x31
v0	equ 0x30

asciiOne	equ 0x34	;monitor ascii vals
asciiTwo	equ 0x35
asciiThree	equ 0x36 

invalMonitor	equ 0x37 ; monitors value in 'in val'

; you may add more data storage declarations here.

chunk	equ 0x2A	;This keeps track of which part of the byte we're reading
					;For example a value of all 1's indicates reading the 4 MSBits (left half) 
					;0's indicate LSBits (right half)
					;So,  chunk = 1111,1111 = reading in [1111],XXXX - MSBs
					;& chunk  = 0000,0000	= reading in XXXX,[1111] - LSBs

scratch equ 0x2B	;where we are storing the inputs. used with 'chunk' 
					;to decide which half of a byte we're reading

saveW	equ 0x2C		;saves W in case it's modified

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; DO NOT CHANGE THIS SECTION
; start defining the program
; jump around the interrupt handler return to the main program
	org	0x0
start		bsf		INTCON,GIE
		bsf		INTCON,INTE
		clrf	semaphore
		goto	main

; handler is supplied to the user
; it reads a 4-bit value from PORTA and stores it in location
; "inval"
; in this assignment, we are assuming that 200 
; cycles passes between interrupts
; do not modify the handler code
	org 0x4
handler	nop
		movwf	saveW			;save w to temp - ADDED
		movf	PORTA,w
		andlw	0x0F			; w = I3,I2,I1,I0, 1111
		movwf	inval			;inval = w
		movwf 	invalMonitor
		movfw	saveW			;restore w to previous state - ADDED
		bsf		semaphore,0
		bcf		INTCON,INTF
		retfie
; end of section not to change
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; beginning of the "real" program
; start by clearing all of the variables to 0
	org 0x100
main
		clrf 	avg
		clrf 	asciiavg
		clrf	asciiavg+1
		clrf	asciiavg+2
		clrf	n3
		clrf	n2
		clrf	n1
		clrf	n0



;		the program sits in this loop waiting for interrupts
;		when a new input value is available, semaphore is set to 1
loop	btfss	semaphore,0
		goto	loop
;		at this point, the location "inval" will have the last
;       	4-bit sensor value read from port A
		bcf		semaphore,0


goto CHECK

;-------------------------------------------------------------------------------
;Sub 'THEN', called when we have a complete 8-bit byte saved

THEN		;subroutine for IF statement

;save second chunk of byte
btfsc	inval,3	;test bit 3 or I3
	bsf	scratch,7;

btfsc inval,2	;bit 2, I2
	bsf scratch,6;

btfsc inval,1	;bit 1, I1
	bsf scratch,5;

btfsc inval,0	;bit 0, I0
	bsf scratch,4;


;if we have a complete byte, then insert into n3, 
;move down the n values and drop last n value

	movfw v1	;move n1 down 
	movwf v0
	movwf n0

	movfw v2	;move n2 down
	movwf v1
	movwf n1

	movfw v3	;move n3 down
	movwf v2
	movwf n2

	;push new scratch value into n3

	movfw scratch	;save to w
	movwf v3		;save w to v3/n3
	movwf n3		
	

;subroutine:	
	;compute the average and save it to avg or whatever
;end sub	

;subroutine:
	;convert avg to asciiavg somehow (not implemented yet)
;end sub

;clear scratch to all 0's
	clrf scratch
	clrw ;clear w
 return
;-------------------------------------------------------------------------------



;-------------------------------------------------------------------------------
;Sub 'ELS', called when we have first half of the byte to save

ELS		;subroutine for IF statement

btfsc	inval,3	;test bit 3 or I3
	bsf	scratch,3;

btfsc inval,2	;bit 2, I2
	bsf scratch,2;

btfsc inval,1	;bit 1, I1
	bsf scratch,1;

btfsc inval,0	;bit 0, I0
	bsf scratch,0;

 return
;-------------------------------------------------------------------------------

CHECK

;first check to see if we have a complete byte
 btfsc	chunk,0;skip sub routine if chunk is all 1's
	call THEN	;IF Above, go to THEN : save second half of byte and process
 btfss	chunk,0
	call ELS	;else - save first half of byte

;toggle chunk bit (complement)
	comf chunk



;		****************************************************	
; 		your calls to your subroutines should be inserted here
;		****************************************************

; 		after the subroutines have returned, the variables <avg,n3, n2, n1, n0, and asciiavg>
;		should have their correct values 



;       	end of user subroutines, return to the loop waiting for the next interrupt
; 		the values of your variables will be verified at this second goto loop statement
done		goto	loop


; 	you may insert code here too if you wish
;	This is a good place to put your subroutines.
					

					

		
		end
